package com.xyxy.platform.modules.core.utils;

import com.xyxy.platform.modules.core.utils.converter.PrimitiveTransformerFactory;
import com.xyxy.platform.modules.core.utils.converter.StringTransformer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 字符串工具类
 * Time: 下午8:33
 * To change this template use File | Settings | File Templates.
 */
public class Strings {
    private static Logger log = LoggerFactory.getLogger(Strings.class);

    /**
     * 拼装各个参数到路径中
     *
     * @param separator, 分隔符
     * @param params,    路径字符串数组
     * @return String, 拼接好的字符串
     */
    public static String combinePath(char separator, String... params) {
        if (null == params || params.length == 0) {
            return StringUtils.EMPTY;
        }
        if (params.length == 1) {
            return params[0];
        }
        StringBuilder sb = new StringBuilder();
        for (String item : params) {
            sb.append(item).append(separator);
        }
        //删除最后一个分割符
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    /**
     * 过滤字段长度,限制字符串长度超过数据库限制
     *
     * @param data   原始数据
     * @param length 数据长度
     * @return 过滤后的数据
     */
    public static String filterWithLengthLimit(String data, int length) {
        if (StringUtils.isNotBlank(data)) {
            data = data.trim();
        }
        if (StringUtils.isNotBlank(data) && data.length() > length) {
            StackTraceElement stack[] = Thread.currentThread().getStackTrace();
            StackTraceElement callerInfo = stack.length > 2 ? stack[2] : stack[0];
            log.warn("数据长度不符:[{}],允许长度:{},调用方:{}", data, length, callerInfo);
            data = data.trim().substring(0, length - 1);
        }
        return data;
    }

    /**
     * 将字符串分割成指定类型的对象列表
     *
     * @param str            待分割的字符串
     * @param separatorChars 分割字符串
     * @param targetClazz    对象类型
     * @param <T>            对象
     * @return 对象列表
     */
    public static <T> List<T> split(String str, String separatorChars,
                                    Class<T> targetClazz) {
        if (StringUtils.isBlank(str)) {
            return new ArrayList<>();
        }
        String[] arr = StringUtils.split(str, separatorChars);
        StringTransformer<T> transformer =
                PrimitiveTransformerFactory.getStringTransformer(targetClazz);
        List<T> result = new ArrayList<>(arr.length);
        T targetItem = null;
        for (String item : arr) {
            targetItem = transformer.transform(item);
            if (null != targetItem) {
                result.add(targetItem);
            }
        }
        return result;
    }

    public static <T> List<T> split(String str, char splitChar,
                                    Class<T> targetClazz) {
        if (StringUtils.isBlank(str)) {
            return new ArrayList<>();
        }
        String[] arr = StringUtils.split(str, splitChar);
        StringTransformer<T> transformer =
                PrimitiveTransformerFactory.getStringTransformer(targetClazz);
        List<T> result = new ArrayList<>(arr.length);
        T targetItem = null;
        for (String item : arr) {
            targetItem = transformer.transform(item);
            if (null != targetItem) {
                result.add(targetItem);
            }
        }
        return result;
    }

    public static <T> Set<T> splitToSet(String str, String splitChar,
                                        Class<T> targetClazz) {
        if (StringUtils.isBlank(str)) {
            return new HashSet<>();
        }
        String[] arr = StringUtils.split(str, splitChar);
        StringTransformer<T> transformer =
                PrimitiveTransformerFactory.getStringTransformer(targetClazz);
        HashSet<T> result = new HashSet<>(arr.length);
        T targetItem = null;
        for (String item : arr) {
            targetItem = transformer.transform(item);
            if (null != targetItem) {
                result.add(targetItem);
            }
        }
        return result;
    }

    public static <T> Set<T> splitToSet(String str, char splitChar,
                                        Class<T> targetClazz) {
        if (StringUtils.isBlank(str)) {
            return new HashSet<>();
        }
        String[] arr = StringUtils.split(str, splitChar);
        StringTransformer<T> transformer =
                PrimitiveTransformerFactory.getStringTransformer(targetClazz);
        HashSet<T> result = new HashSet<>(arr.length);
        T targetItem = null;
        for (String item : arr) {
            targetItem = transformer.transform(item);
            if (null != targetItem) {
                result.add(targetItem);
            }
        }
        return result;
    }

    /**
     * 将字符串转换为指定的对象类型
     *
     * @param str         字符串
     * @param targetClazz 目标类型
     * @param defaultVal  默认值
     * @param <T>         转换类型
     * @return 对应对象
     */
    public static <T> T to(String str, Class<T> targetClazz, T defaultVal) {
        StringTransformer<T> transformer =
                PrimitiveTransformerFactory.getStringTransformer(targetClazz);
        if (null != transformer) {
            return transformer.transform(str, defaultVal);
        }
        return defaultVal;
    }

    /**
     * 将字符串转换为指定的对象类型
     *
     * @param str         字符串
     * @param targetClazz 目标类型
     * @param <T>         转换类型
     * @return 对应对象
     */
    public static <T> T to(String str, Class<T> targetClazz) {
        return to(str, targetClazz, null);
    }

    private static final char DEFAULT_SEPARATOR = '_';

    /**
     * Convert a name in camelCase to an underscored name in lower case.
     * Any upper case letters are converted to lower case with a preceding underscore.
     *
     * @param name the string containing original name
     * @return the converted name
     */
    private String toUnderscoreCase(String name) {
        if (StringUtils.isBlank(name)) {
            return "";
        }
        StringBuilder result = new StringBuilder();
        result.append(name.substring(0, 1).toLowerCase());
        for (int i = 1; i < name.length(); i++) {
            String s = name.substring(i, i + 1);
            String slc = s.toLowerCase();
            if (!s.equals(slc)) {
                result.append(DEFAULT_SEPARATOR).append(slc);
            } else {
                result.append(s);
            }
        }
        return result.toString();
    }

    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == DEFAULT_SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    public static String toCapitalizeCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = toCamelCase(s);
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    public static void main(String[] args) {
        Strings.filterWithLengthLimit("111111111111`11111", 5);
        int a = "0".compareTo("1");
        log.info("{}", a);
//        Map<String, Object> params = new TreeMap<String, Object>();
//        params.put("1", 2);
//        params.put("2", 3);
//        params.put("3", 4);
//        log.info(params.toString());

    }
}
